package com.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.config.CustomRealm;
import com.pojo.SysRight;
import com.pojo.SysRole;
import com.pojo.SysRoleRight;
import com.service.RoleRightService;
import com.service.RoleService;
import com.service.SysRightService;
import com.service.UserService;
import com.utils.PageUtile;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/role")
public class RoleController {

    @Autowired
    RoleService roleService;

    @Autowired
    SysRightService sysRightService;

    @Autowired
    RoleRightService roleRightService;

    @Autowired
    UserService userService;
    /**
     * 角色管理跳转
     */
    @RequestMapping("/list")
    public Object roleList(SysRole sysRole,@RequestParam(defaultValue = "1")Integer pageIndex,
                           @RequestParam(defaultValue = "2")Integer pageSize,
                           Model model){
        IPage<SysRole> page = new Page<SysRole>(pageIndex,pageSize);
        QueryWrapper<SysRole> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda()
                .like(StringUtils.hasText(sysRole.getRoleName()),
                 SysRole::getRoleName, sysRole.getRoleName());
        Page<SysRole> page1=(Page<SysRole>)roleService.page(page,queryWrapper);
        PageUtile<SysRole> pageUtile=new PageUtile<SysRole>();
        //复制对象的值
        BeanUtils.copyProperties(page1, pageUtile);
        model.addAttribute("rolePage",pageUtile);
        model.addAttribute("roleName",sysRole.getRoleName());
        return "role/list";
    }

    /**
     * 跳转添加
     * @param model
     * @return
     */
    @RequestMapping("/add")
    public Object toAdd(Model model){
        model.addAttribute("rights",sysRightService.list());
        return "role/add";
    }

    /**
     * 添加,修改
     */
    @RequestMapping("save")
    @Transactional
    public Object saveOrUpdate(SysRole sysRole,String[] rightCodes,Model model){
        boolean result=roleService.saveOrUpdate(sysRole);
        if (result){
            //先删除原有的权限,再添加新的权限
            QueryWrapper<SysRoleRight> queryWrapper=new QueryWrapper<>();
            queryWrapper.lambda().eq(SysRoleRight::getRfRoleId,sysRole.getRoleId());
            roleRightService.remove(queryWrapper);

            //新增角色成功则将角色权限添加
            List<SysRoleRight> list=new ArrayList<>();
            for (String rightCode:rightCodes){
                SysRoleRight sysRoleRight=new SysRoleRight();
                sysRoleRight.setRfRightCode(rightCode);
                sysRoleRight.setRfRoleId(sysRole.getRoleId());
                list.add(sysRoleRight);
            }
            roleRightService.saveBatch(list);
            ///刷新shiro过滤器中的权限
            reloadFilterChainDefinitions();
            //清除所有缓存方法
            reloadCacheAuthori();
            return "redirect:/role/list";
        }else if (sysRole.getRoleId()==0){
            return "redirect:/role/add";
        }else {
            return "redirect:/role/edit?usrId="+sysRole.getRoleId();
        }
    }

    private void reloadCacheAuthori(){
        //清除当前登录用户的权限缓存
        DefaultWebSecurityManager defaultWebSecurityManager= (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
        Collection<Realm> realms=defaultWebSecurityManager.getRealms();
        if (realms!=null && !realms.isEmpty()){
            Iterator var3=realms.iterator();
            while (var3.hasNext()){
                Realm realm=(Realm)var3.next();
                if (realm instanceof CustomRealm){
                    CustomRealm tempReaml=(CustomRealm)realm;
                    tempReaml.clearAllCachedAuthorizationInfo();
                }
            }
        }
    }

    /**
     * 跳转修改
     * @param roleId
     * @param model
     * @return
     */
    @RequestMapping("/edit")
    public Object toEdit(long roleId,Model model){
        model.addAttribute("role",roleService.getById(roleId));
        model.addAttribute("rights",sysRightService.list());
        //获取用户拥有的权限
        List<SysRoleRight> roleRightList=userService.getRightListByRoleId(roleId);
        Set<String> roleRights=roleRightList.stream()
                .map(roleRight-> roleRight.getRfRightCode())
                .collect(Collectors.toSet());
        model.addAttribute("roleRights",roleRights);
        return "role/edit";
    }

    private Map<String,String> loadFilterChainDefinitions(){
        //配置资源认证规则
        Map<String,String> urlMap=new LinkedHashMap<>();
        urlMap.put("/css/*", "anon");
        urlMap.put("/js/*", "anon");
        urlMap.put("/fonts/*", "anon");
        urlMap.put("/images/*", "anon");
        urlMap.put("/localcss/*", "anon");
        urlMap.put("/localjs/*", "anon");
        urlMap.put("/doLogin", "anon");
        urlMap.put("/logout", "anon");
        //登录页面
        urlMap.put("/", "anon");
        List<SysRight> rightList=sysRightService.list();
        for (SysRight sysRight:rightList) {
            if (StringUtils.hasText(sysRight.getRightUrl())){
                urlMap.put(sysRight.getRightUrl(), "perms["+sysRight.getRightCode()+"]");
            }
        }
        urlMap.put("/*", "authc");
        return urlMap;
    }

    private void reloadFilterChainDefinitions(){//重新加载动态权限,配置权限验证规则
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            ServletContext servletContext=request.getSession().getServletContext();
            AbstractShiroFilter shiroFilter=(AbstractShiroFilter) WebApplicationContextUtils
                    .getRequiredWebApplicationContext(servletContext).getBean("shiroFilterFactory");
            synchronized (shiroFilter){
                //获取过滤管理器
                PathMatchingFilterChainResolver filterChainResolver=(PathMatchingFilterChainResolver)shiroFilter.getFilterChainResolver();
                DefaultFilterChainManager manager=(DefaultFilterChainManager)filterChainResolver.getFilterChainManager();
                //清空初始化权限设置
                manager.getFilterChains().clear();
                //重新加载动态权限,配置权限验证规则
                Map<String,String>chains=loadFilterChainDefinitions();
                for(Map.Entry<String,String>entry:chains.entrySet()){
                    String url=entry.getKey();
                    String chainDefinition=entry.getValue().trim().replace("", "");
                    manager.createChain(url, chainDefinition);
                }
                System.out.println("更新权限成功!!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
